package service

import (
	"bufio"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"mini-gde/client"
	"os"
	"path/filepath"
	"strings"

	"github.com/docker/docker/pkg/archive"
	"k8s.io/client-go/util/homedir"

	"github.com/docker/docker/api/types"
)

type Image struct {
	Id         string `json:"Id"`
	Created    int64
	Repository string
	Tags       string
	Size       int64
}

var authConfig = types.AuthConfig{
	Username: "chintensakai",
	Password: "gaosan16ban",
}

func GetImages() []Image {
	// ctx := context.Background()

	// cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation(),
	// 	client.WithHost("tcp://192.168.1.248:2375"))

	// 本地
	// cli, err := client.NewClientWithOpts(client.FromEnv)
	// if err != nil {
	// 	panic(err)
	// }

	images, err := client.Client.ImageList(client.Ctx, types.ImageListOptions{})

	result := make([]Image, 0, len(images))
	if err != nil {
		panic(err)
	}

	for _, image := range images {
		tmp := Image{
			Id:         image.ID[8:24],
			Created:    image.Created,
			Repository: strings.Split(image.RepoTags[0], ":")[0],
			Tags:       strings.Split(image.RepoTags[0], ":")[1],
			Size:       image.Size,
		}
		result = append(result, tmp)
	}
	return result
}

// build image
func BuildImageByDockerfile(images string) error {
	path := homedir.HomeDir() + "/tmp/apps"
	tar, err := archive.TarWithOptions(path+"/"+images+"/", &archive.TarOptions{})
	fmt.Println(path + "/" + images + "/")
	if err != nil {
		fmt.Println(err)
		return err
	}
	tag := "192.168.1.248:5000/" + images + ":0.0.1"
	opts := types.ImageBuildOptions{
		Dockerfile: "Dockerfile",
		Tags:       []string{tag},
		Remove:     true,
	}
	res, err := client.Client.ImageBuild(client.Ctx, tar, opts)
	fmt.Println(res.Body)
	if err != nil {
		fmt.Println(err)
		return err
	}

	defer res.Body.Close()
	scanner := bufio.NewScanner(res.Body)
	for scanner.Scan() {
		lastLine := scanner.Text()
		fmt.Println(lastLine)
	}
	err = imagePush(tag)
	if err != nil {
		fmt.Println(err)
		return err
	}
	//destorytemp(path)
	return nil
}

func destorytemp(path string) {

	filepath.Walk(path, func(path string, fi os.FileInfo, err error) error {
		if nil == fi {
			return err
		}
		if !fi.IsDir() {
			return nil
		}
		name := fi.Name()

		if strings.Contains(name, "temp") {

			fmt.Println("temp file name:", path)

			err := os.RemoveAll(path)
			if err != nil {
				fmt.Println("delet dir error:", err)
			}
		}
		return nil
	})

}

// push image
func imagePush(tag string) error {
	authConfigBytes, _ := json.Marshal(authConfig)
	authConfigEncoded := base64.URLEncoding.EncodeToString(authConfigBytes)

	opts := types.ImagePushOptions{RegistryAuth: authConfigEncoded}
	rd, err := client.Client.ImagePush(client.Ctx, tag, opts)
	if err != nil {
		return err
	}

	defer rd.Close()
	// 打印镜像推送的输出
	_, err = io.Copy(os.Stdout, rd)
	if err != nil {
		fmt.Println("Err: read image push response error,", err.Error())
		return err
	}
	return nil
}
